package priv.happy.mealpickpro.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import priv.happy.mealpickpro.domain.Food;
import priv.happy.mealpickpro.domain.FoodTag;
import priv.happy.mealpickpro.domain.Tag;
import priv.happy.mealpickpro.dto.AddFoodDTO;
import priv.happy.mealpickpro.dto.FoodDTO;
import priv.happy.mealpickpro.dto.UserFoodCount;
import priv.happy.mealpickpro.mapper.FoodMapper;
import priv.happy.mealpickpro.service.FoodService;
import priv.happy.mealpickpro.service.FoodTagService;
import priv.happy.mealpickpro.service.TagService;
import priv.happy.mealpickpro.service.UserMealService;
import priv.happy.mealpickpro.util.ImgUtilv2;
import priv.happy.mealpickpro.vo.FoodVO;

import java.io.IOException;
import java.time.Duration;
import java.util.*;

/**
 * @author HAPPY
 * @description 针对表【food】的数据库操作Service实现
 * @createDate 2023-07-02 11:23:42
 */
@Service
public class FoodServiceImpl extends ServiceImpl<FoodMapper, Food>
        implements FoodService {
    @Autowired
    FoodMapper foodMapper;
    @Autowired
    UserMealService userMealService;
    @Autowired
    TagService tagService;
    @Autowired
    FoodTagService foodTagService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public FoodVO pickFood(FoodDTO foodDTO) {
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();

        FoodVO pickFood = null;
        List<Food> foodList;
        // 如果标签没有修改，先看缓存中有没有选餐记录，有的话拿缓存中的数据
        String foodListStr = operations.get("mealpickpro:pick:" + foodDTO.getUserId());
        if (foodListStr != null && !"[]".equals(foodListStr) && !foodDTO.getIsChanged()) {
            // 从缓存获取
            foodList = JSONUtil.toList(foodListStr, Food.class);
        } else {
            // 从数据库生成
            foodList = new ArrayList<>(foodMapper.pickFood(foodDTO));
        }
        // 如果当前不为空
        if (!foodList.isEmpty()) {
            int randomNumber = getRandomNumber(foodList.size());
            // 随机取一个
            Food food = foodList.get(randomNumber);
            List<Tag> foodTagList = tagService.getFoodTagList(food.getId());
            pickFood = new FoodVO().setId(food.getId())
                    .setName(food.getName()).setDescription(food.getDescription())
                    .setPrice(food.getPrice())
                    .setPhotoUrl(food.getPhotoUrl()).setTagList(foodTagList);
            // 删除当前所生成的食物
            foodList.remove(randomNumber);
            // 刷新缓存, 有效期一分钟
            operations.set("mealpickpro:pick:" + foodDTO.getUserId(), JSONUtil.toJsonStr(foodList), Duration.ofSeconds(60));
        }
        return pickFood;
    }

    @Override
    public boolean removeFoodById(Integer foodId, Integer userId) {
        // 普通用户仅能删除自己上传的食物，其他人上传的食物无法删除
        if (getById(foodId) != null && (Objects.equals(getById(foodId).getPostUserId(), userId) || "管理员".equals(userMealService.getById(userId).getRole()))) {
            try {
                // 删除食物
                removeById(foodId);
                // 删除该食物所有的标签
                Map<String, Object> delFood = new HashMap<>();
                delFood.put("food_id", foodId);
                foodTagService.removeByMap(delFood);
                return true;
            } catch (Exception e) {
                return false;
            }
        }
        return false;
    }

    @Override
    public List<UserFoodCount> countUserFoods() {
        return foodMapper.countUserFoods();
    }


    @Override
    public int addFood(AddFoodDTO addFoodDTO) throws IOException {
        // 校验上传的图像格式
        if (addFoodDTO.getImgName() != null) {
            if (!"jpg".equalsIgnoreCase(addFoodDTO.getImgName().split("\\.")[1])
                    && !"png".equalsIgnoreCase(addFoodDTO.getImgName().split("\\.")[1])
                    && !"jpeg".equalsIgnoreCase(addFoodDTO.getImgName().split("\\.")[1])) {

                return 1;
            }
        }
        // 新增食物
        Food food = new Food().setName(addFoodDTO.getFoodName())
                .setPrice(addFoodDTO.getPrice())
                .setDescription(addFoodDTO.getDescription())
                .setPostUserId(addFoodDTO.getPostUserId())
                .setPostTime(DateUtil.now())
                .setAddressId(addFoodDTO.getAddressId());
        // 如果没有上传图片，则设置为默认图片
        if (addFoodDTO.getImgName() != null) {
            food.setPhotoUrl(ImgUtilv2.imageShowFoodFolder + addFoodDTO.getImgName());
        } else {
            food.setPhotoUrl(ImgUtilv2.imageShowDefaultFoodPicture);
        }
        try {
            save(food);
            // 添加食物对应标签
            List<FoodTag> foodTagList = new ArrayList<>();
            for (int i = 0; i < addFoodDTO.getTagList().size(); i++) {
                foodTagList.add(new FoodTag().setFoodId(food.getId()).setTagId(addFoodDTO.getTagList().get(i).getId())
                        .setPostTime(DateUtil.now()));
            }
            foodTagService.saveBatch(foodTagList);
            // 将图像写入本地文件
            ImgUtilv2.saveBase64ToImage(addFoodDTO.getImgBase64Code(), ImgUtilv2.imageSaveFoodFolder + addFoodDTO.getImgName());
            return 0;
        } catch (Exception e) {
            return 2;
        }
    }

    @Override
    public int modifyFood(AddFoodDTO modifyFoodDTO) throws IOException {
        // 校验上传的图像格式
        if (modifyFoodDTO.getImgName() != null) {
            if (!"jpg".equalsIgnoreCase(modifyFoodDTO.getImgName().split("\\.")[1])
                    && !"png".equalsIgnoreCase(modifyFoodDTO.getImgName().split("\\.")[1])
                    && !"jpeg".equalsIgnoreCase(modifyFoodDTO.getImgName().split("\\.")[1])) {

                return 1;
            }
        }
        // 新增食物
        Food food = new Food()
                .setId(modifyFoodDTO.getId())
                .setName(modifyFoodDTO.getFoodName())
                .setPrice(modifyFoodDTO.getPrice())
                .setDescription(modifyFoodDTO.getDescription())
                .setPostUserId(modifyFoodDTO.getPostUserId())
                .setLastModifyTime(DateUtil.now())
                .setAddressId(modifyFoodDTO.getAddressId());

        // 如果没有上传图片，则设置为默认图片
        if (modifyFoodDTO.getImgName() != null) {
            String imgPath = ImgUtilv2.imageShowFoodFolder + modifyFoodDTO.getImgName();
            food.setPhotoUrl(imgPath);
        } else {
            // 如果本次没有上传图片，则不修改
            food.setPhotoUrl(null);
        }

        try {
            updateById(food);

            // 删除所有的旧标签
            Map<String, Object> delFood = new HashMap<>();
            delFood.put("food_id", food.getId());
            foodTagService.removeByMap(delFood);

            // 添加食物对应标签
            List<FoodTag> foodTagList = new ArrayList<>();
            for (int i = 0; i < modifyFoodDTO.getTagList().size(); i++) {
                foodTagList.add(new FoodTag().setFoodId(food.getId()).setTagId(modifyFoodDTO.getTagList().get(i).getId())
                        .setPostTime(DateUtil.now()));
            }
            foodTagService.saveBatch(foodTagList);
            // 将图像写入本地文件
            ImgUtilv2.saveBase64ToImage(modifyFoodDTO.getImgBase64Code(), ImgUtilv2.imageSaveFoodFolder + modifyFoodDTO.getImgName());
            return 0;
        } catch (Exception e) {
            return 2;
        }
    }

    /**
     * 根据当前生成的食物集合生成随机索引
     *
     * @param size 集合大小
     * @return 返回生成的随机索引
     */
    private int getRandomNumber(int size) {
        // 生成随机食物索引
        int min = 0;
        int max = size - 1;
        // 创建Random对象
        Random random = new Random();
        // 生成随机数
        int randomNumber = random.nextInt(max - min + 1) + min;
        return randomNumber;
    }
}




